广域网是由很多的局域网组成的,比如公司网络、家庭网络、校园网络等。之前我们一直在讨论广域网的设计,今天我们到微观层面,看看局域网是如何工作的。

IPv4 的地址不够,因此需要设计子网。当一个公司申请得到一个公网 IP 后,会在自己的公司内部设计一个局域网。这个局域网所有设备的 IP 地址,通常会以 192.168 开头。这个时候,假设你的职工小明,上班时间玩王者荣耀。当他用 UDP 协议向王者荣耀的服务器发送信息时,消息的源 IP 地址是一个内网 IP 地址,而王者荣耀的服务,是一个外网 IP 地址。

这里我先向你提一个问题,数据到王者荣耀服务器可以通过寻址和路由找到目的地,但是数据从王者荣耀服务器回来的时候,王者荣耀服务器如何知道192.168开头的地址应该如何寻址呢?要想回答这个问题,就涉及网络地址转换协议(NAT 协议)。

内部网络和外部网络

对一个组织、机构、家庭来说,我们通常把内部网络称为局域网,外部网络就叫作外网。下图是一个公司多个部门的网络架构。

我们会看到外网通过路由器接入整个公司的局域网,和路由器关联的是三台交换机,代表公司的三个部门。交换机,或者称为链路层交换机,通常工作在链路层;而路由器通常也具有交换机的能力,工作在网络层和链路层

光纤是一种透明的导光介质,多束光可以在一个介质中并行传播,不仅信号容量大,重量轻,并行度高而且传播距离远。当然,光纤不能弯曲,因此办公室里用来连接交换机和个人电脑的线路肯定不能是光纤,光线通常都用于主干网络

局域网数据交换(MAC 地址)

接下来我们讨论下同一个局域网中的设备如何交换消息。

首先,我们先明确一个概念,设备间通信的本质其实是设备拥有的网络接口(网卡)间的通信。为了区别每个网络接口,互联网工程任务组(IETF)要求每个设备拥有一个唯一的编号,这个就是 MAC 地址。

你可能会问:IP 地址不也是唯一的吗?其实不然,一旦设备更换位置,比如你把你的电脑从北京邮寄的广州,那么 IP 地址就变了,而电脑网卡的 MAC 地址不会发生变化。总的来说,IP 地址更像现实生活中的地址,而 MAC 地址更像你的身份证号。

然后,我们再明确另一个基本的概念。在一个局域网中,我们不可以将消息从一个接口(网卡)发送到另一个接口(网卡),而是要通过交换机。为什么是这样呢?因为两个网卡间没有线啊!所以数据交换,必须经过交换机,毕竟线路都是由网卡连接交换机的。

总结下,数据的发送方,将自己的 MAC 地址、目的地 MAC 地址,以及数据作为一个分组(Packet),也称作 Frame 或者封包,发送给交换机。交换机再根据目的地 MAC 地址,将数据转发到目的地的网络接口(网卡)。

最后一个问题,你可能问,这个分组或者 Frame,是不是 IP 协议的分组呢?——不是,这里提到的是链路层的数据交换,它支持 IP 协议工作,是网络层的底层。所以,如果 IP 协议要传输数据,就要将数据转换成为链路层的分组,然后才可以在链路层传输

链路层分组大小受限于链路层的网络设备、线路以及使用了链路层协议的设计。你有时候可能会看到 MTU 这个缩写词,它指的是 Maximun Transmission Unit,最大传输单元,意思是链路层网络允许的最大传输数据分组的大小。因此 IP 协议要根据 MTU 拆分封包

之前介绍 TCP 协议滑动窗口的时候,还提到过一个词,叫作 MSS,这里我们复习下。MSS(Maximun Segment Size,最大段大小)是 TCP 段,或者称为 TCP 分组(TCP Packet)的最大大小。MSS 是传输层概念,MTU 是链路层概念

可能有细心的同学可以能会意识到,这不就是下面这样一个数学关系吗?

1
MTU = MSS + TCP Header + IP Header

这个思路有一定道理,但是不对。先说说这个思路怎么来的,你可能会这么思考:TCP 传输数据大于 MSS,就拆包。每个封包加上 TCP Header ,之后经过 IP 协议,再加上 IP Header。于是这个加上 IP 头的分组(Packet)不能超过 MTU。固然这个思路很有道理,可惜是错的。因为 TCP 解决的是广域网的问题,MTU 是一个链路层的概念,要知道不同网络 MTU 是不同的,所以二者不可能产生关联。这也是为什么 IP 协议还可能会再拆包的原因

地址解析协议(ARP)

上面我们讨论了 MAC 地址,链路层通过 MAC 地址定位网络接口(网卡)。在一个网络接口向另一个网络接口发送数据的时候,至少要提供这样 3 个字段:

  1. 源 MAC 地址
  2. 目标 MAC 地址
  3. 数据

这里我们一起再来思考一个问题,对于一个网络接口,它如何能知道目标接口的 MAC 地址呢?我们在使用传输层协议的时候,清楚地知道目的地的 IP 地址,但是我们不知道 MAC 地址。这个时候,就需要一个中间服务帮助根据 IP 地址找到 MAC 地址——这就是地址解析协议(Address Resolution Protocol,ARP)

整个工作过程和 DNS 非常类似,如果一个网络接口已经知道目标 IP 地址对应的 MAC 地址了,它会将数据直接发送给交换机,交换机将数据转发给目的地。那么如果网络接口不知道目的地地址呢?这个时候,地址解析协议就开始工作了。发送接口会发送一个广播查询给到交换机,交换机将查询转发给所有接口。

如果某个接口发现自己就是对方要查询的接口,则会将自己的 MAC 地址回传。接下来,会在交换机和发送接口的 ARP 表中,增加一个缓存条目。也就是说,接下来发送接口再次向 IP 地址 2.2.2.2 发送数据时,不需要再广播一次查询了。

前面提到这个过程和 DNS 非常相似,采用的是逐级缓存的设计减少 ARP 请求。发送接口先查询本地的 ARP 表,如果本地没有数据,然后广播 ARP 查询。这个时候如果交换机中有数据,那么查询交换机的 ARP 表;如果交换机中没有数据,才去广播消息给其他接口。注意,ARP 表是一种缓存,也要考虑缓存的设计。通常缓存的设计要考虑缓存的失效时间、更新策略、数据结构等。比如可以考虑用 TTL(Time To Live)的设计,为每个缓存条目增加一个失效时间。另外,更新策略可以考虑利用老化(Aging)算法模拟 LRU。

请你思考路由器和交换机的异同点。不知道你有没有在网上订购过家用无线路由器,通常这种家用设备也会提供局域网,具备交换机的能力。同时,这种设备又具有路由器的能力。所以,很多同学可能会分不清路由器和交换机。总的来说,家用的路由器,也具备交换机的功能。但是当 ARP 表很大的时候,就需要专门的、能够承载大量网络接口的交换设备。就好比,如果用数组实现 ARP 表,数据量小的时候,遍历即可;但如果数据量大的话,就需要设计更高效的查询结构和设计缓存。

连接内网

有时候,公司内部有多个子网。这个时候一个子网如果要访问另一个子网,就需要通过路由器

也就是说,图中的路由器,其实充当了两个子网通信的桥梁。在上述过程中,发送接口不能直接通过 MAC 地址发送数据到接收接口,因为子网 1 的交换机不知道子网 2 的接口。这个时候,发送接口需要通过 IP 协议,将数据发送到路由器,再由路由器转发信息到子网 2 的交换机。这里提一个问题,子网 2 的交换机如何根据 IP 地址找到接收接口呢?答案是通过查询 ARP 表。

连接外网(网络地址转换技术,NAT)

最后我们讨论下连接外网的问题。IPv4 协议因为存在网络地址耗尽的问题,不能为一个公司提供足够的地址,因此内网 IP 可能会和外网重复。比如内网 IP 地址192.168.0.1发送信息给22.22.22.22,这个时候,其实是跨着网络的。

跨网络必然会通过多次路由,最终将消息转发到目的地。但是这里存在一个问题,寻找的目标 IP 地址22.22.22.22是一个公网 IP,可以通过正常的寻址 + 路由算法定位。当22.22.22.22寻找192.168.0.1的时候,是寻找一个私网 IP,这个时候是找不到的。解决方案就是网络地址转换技术(NAT,Network Address Translation),如下图所示:

NAT 技术转换的是 IP 地址,私有 IP 通过 NAT 转换为公网 IP 发送到服务器。服务器的响应,通过 NAT 转换为私有 IP,返回给客户端。通过这种方式,就解决了内网和外网的通信问题。

小结

链路层发送数据靠的是 MAC 地址,MAC 地址就好像人的身份证一样。局域网中,数据不可能从一个终端直达另一个终端,而是必须经过交换机交换。交换机也叫作链路层交换机,它的工作就是不断接收数据,然后转发数据。通常意义上,交换机不具有路由功能,路由器往往具有交换功能。但是往往路由器交换的效率,不如交换机。已知 IP 地址,找到 MAC 地址的协议,叫作地址解析协议(ARP)。

网络和网络的衔接,必须有路由器(或者等价的设备)。一个网络的设备不能直接发送链路层分组给另一个网络的设备,而是需要通过 IP 协议让路由器转发。

现在可以来回答本讲关联的面试题目:网络地址转换协议是如何工作的?

网络地址解析协议(NAT)解决的是内外网通信的问题。NAT 通常发生在内网和外网衔接的路由器中,由路由器中的 NAT 模块提供网络地址转换能力。从设计上看,NAT 最核心的能力,就是能够将内网中某个 IP 地址映射到外网 IP,然后再把数据发送给外网的服务器。当服务器返回数据的时候,NAT 又能够准确地判断外网服务器的数据返回给哪个内网 IP。你可以思考下 NAT 是如何做到这点的呢?需要做两件事。

  1. NAT 需要作为一个中间层替换 IP 地址。 发送的时候,NAT 替换源 IP 地址(也就是将内网 IP 替换为出口 IP);接收的时候,NAT 替换目标 IP 地址(也就是将出口 IP 替换回内网 IP 地址)。
  2. NAT 需要缓存内网 IP 地址和出口 IP 地址 + 端口的对应关系。也就是说,发送的时候,NAT 要为每个替换的内网 IP 地址分配不同的端口,确保出口 IP 地址+ 端口的唯一性,这样当服务器返回数据的时候,就可以根据出口 IP 地址 + 端口找到内网 IP。

下面举一个NAT示例:

举个例子,客户端172.18.250.6和百度服务器202.108.22.5通信,172.18.250.6发送数据时,先转换为219.155.6.240:1723(任意>1024的随机端口),然后再利用这个身份发送数据给百度服务器,然后百度服务器回应数据并发送给219.155.6.240:1723,NAT网关检查自己的关联表,意识到这是自己地私网中172.18.250.6的数据包,然后把这个数据发送给客户端。也就是说,我们利用端口号的唯一性实现了公网ip转换为私网ip的这一步。PAT(NAT重载)能够使用传输层端口号来标识主机,因此,从理论上说,最多可让大约65000台主机共用一个公有IP地址。

思考题

IPv6 协议还需要 NAT 吗?

IPv6 解决了 IP 耗尽的问题,为机构、组织、公司、家庭等网络提供了充足的 IP 资源,从这个角度看是不是就不需要 NAT 协议了呢?

在没有 IPv6 之前,NAT 是 IP 资源耗尽的主流解决方案。在一个内网中的全部设备通过 NAT 协议共享一个外网的 IPv4 地址,是目前内外网对接的主要方式。IPv6 地址资源充足,可以给全球每个设备一个独立的地址。从这个角度看 IPv6 的确不需要 NAT 协议。但是目前的情况,是 IPv6 网络还没有完全普及。尽管很多公司已经支持自己的互联网产品可以使用 IPv6 访问,但是公司内部员工使用的内部网络还是 IPv4。如果要连接 IPv6 和 IPv4 网络,仍然需要 NAT 协议(NAT64),这个协议可以让多个 IPv6 的设备共享一个 IPv4 的公网地址。

参考:

https://blog.csdn.net/legnyu880412/article/details/88084686

https://kaiwu.lagou.com/course/courseInfo.htm?courseId=837#/detail/pc?id=7273